package com.jcp.util;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 人脸识别的工具类
 * 
 * 作用：获取access_token、上传人脸数据到人脸库、与人脸库中人脸数据进行对比、修改人脸库中的人脸数据、
 * 对比两个本地的人脸数据、人脸检测与属性分析、用户信息查询、获取用户人脸列表、
 * 获取指定组的用户列表、创建用户组、删除用户组、组列表查询、公安验证、在线活体检测、人脸融合
 * 
 * author：戴布斯
 */
public class FaceIDUtil {
	// 线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取
	public static String accessToken = "24.18019ecfb22d9288273971b151981c7b.2592000.1571834425.282335-17307452";

	// 用来获取权限token,返回值类型String
	public static String getAuth() {
		// 百度人脸识别接口的 API Key
		String clientId = "T8TOeXeiyoC6GIpV3tEcegyn";// 戴布斯的API Key
		// 百度人脸识别接口的Secret Key
		String clientSecret = "44Ru3gBZyIo0hkuE1copoxst4vsX7BM2";// 戴布斯的Secret Key
		// 获取token地址
		String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
		String getAccessTokenUrl = authHost
				// 1. grant_type为固定参数
				+ "grant_type=client_credentials"
				// 2. 百度人脸识别接口的 API Key
				+ "&client_id=" + clientId
				// 3. 百度人脸识别接口的Secret Key
				+ "&client_secret=" + clientSecret;
		try {
			URL realUrl = new URL(getAccessTokenUrl);
			// 打开和URL之间的连接
			HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			// 获取所有响应头字段
			Map<String, List<String>> map = connection.getHeaderFields();
			// 遍历所有的响应头字段
			for (String key : map.keySet()) {
				System.err.println(key + "--->" + map.get(key));
			}
			// 定义 BufferedReader输入流来读取URL的响应
			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String result = "";
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}

			// 控制台输出人脸库的返回结果
			System.err.println("result:" + result);

			// 解析json，得到access_token
			JSONObject jsonObject = new JSONObject(result);
			String access_token = jsonObject.getString("access_token");

			return access_token;// 返回值
		} catch (Exception e) {
			System.err.printf("获取token失败！");
			e.printStackTrace(System.err);
		}
		return null;
	}

	// 上传人脸数据到人脸库，参数为用户ID及要上传的照片地址，返回值类型为boolean(添加结果)
	// 用来
	public static boolean addFace(int userId, String base) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
		try {

			Map<String, Object> map = new HashMap<>();
			map.put("image", base);// 图片信息
			map.put("group_id", "jcp");// 用户组
			map.put("user_id", userId);// 用户ID
			map.put("liveness_control", "NONE");// 活体检测
			map.put("image_type", "BASE64");// 图片类型
			map.put("quality_control", "NONE");// 图片质量
			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			JSONObject json = new JSONObject(result);

			// 添加人脸的错误码，0为没有错误，!0为有错
			String errorCode = json.get("error_code").toString();
			System.out.println(errorCode);
			if (errorCode.equals("0")) {
				System.out.println("人脸注册成功");
				return true;
			} else {
				return false;

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	// 将上传的人脸数据在人脸库中搜索，返回最匹配且相似度85以上的用户的ID
	// 用来打卡以及登录
	public static int searchFace(String base) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/search";
		try {

			Map<String, Object> map = new HashMap<>();
			map.put("image", base);
			map.put("liveness_control", "NONE");
			map.put("group_id_list", "jcp");
			// map.put("user_id", userId);
			map.put("image_type", "BASE64");
			map.put("quality_control", "NONE");

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);

			JSONObject json = new JSONObject(result);

			// 人脸搜索对比的错误码，0为没有错误，!0为有错
			String errorCode = json.get("error_code").toString();
			System.out.println(errorCode);

			// 对json的解析
			JSONObject result2 = json.getJSONObject("result");
			System.out.println(result2);
			JSONArray userList = result2.getJSONArray("user_list");
			System.out.println(userList);
			JSONObject userList2 = userList.getJSONObject(0);
			System.out.println(userList2);

			// 上传的人脸数据与人脸库中最匹配的人脸数据的相似度
			float score = Float.parseFloat(userList2.get("score").toString());
			System.out.println(score);

			// 人脸数据最匹配的用户的ID
			int userId = Integer.parseInt(userList2.get("user_id").toString());
			System.out.println(userId);

			if (!errorCode.equals("0")) {
				System.out.println("识别过程中出现错误错误");
				return 0;
			} else if (score >= 75.0) {
				System.out.println("识别成功，用户是：" + userId + "，相似度是" + score);
				return userId;
			} else {
				System.out.println("识别失败");
				return 0;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	// 修改人脸库上的人脸信息
	public static String updateFace(int userId, String imgAddress) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/update";
		try {
			byte[] bytes1 = FileUtil.readFileByBytes(imgAddress);// 【本地文件地址】
			String img = Base64Util.encode(bytes1);

			Map<String, Object> map = new HashMap<>();
			map.put("image", img);
			map.put("group_id", "jcp");
			map.put("user_id", userId);// 要修改的用户ID
			map.put("user_info", "cba");
			map.put("liveness_control", "NORMAL");
			map.put("image_type", "BASE64");
			map.put("quality_control", "LOW");

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 对比本地的两个人脸数据
	public static String match(String imgAddress1, String imgAddress2) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
		try {

			byte[] bytes1 = FileUtil.readFileByBytes(imgAddress1);// 【本地文件1地址】
			byte[] bytes2 = FileUtil.readFileByBytes(imgAddress2);// 【本地文件2地址】
			String image1 = Base64Util.encode(bytes1);
			String image2 = Base64Util.encode(bytes2);

			List<Map<String, Object>> images = new ArrayList<>();

			Map<String, Object> map1 = new HashMap<>();
			map1.put("image", image1);
			map1.put("image_type", "BASE64");
			map1.put("face_type", "LIVE");
			map1.put("quality_control", "LOW");
			map1.put("liveness_control", "NORMAL");

			Map<String, Object> map2 = new HashMap<>();
			map2.put("image", image2);
			map2.put("image_type", "BASE64");
			map2.put("face_type", "LIVE");
			map2.put("quality_control", "LOW");
			map2.put("liveness_control", "NORMAL");

			images.add(map1);
			images.add(map2);

			String param = GsonUtils.toJson(images);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 人脸检测与属性分析
	public static String detect(String imgAddress) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
		try {
			byte[] bytes = FileUtil.readFileByBytes(imgAddress);// 【本地文件地址】
			String image1 = Base64Util.encode(bytes);

			Map<String, Object> map = new HashMap<>();
			map.put("image", image1);
			map.put("face_field", "faceshape,facetype");
			map.put("image_type", "BASE64");

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 用户信息查询
	public static String getUserInfo(int userId) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/get";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("user_id", userId);
			map.put("group_id", "jcp");

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 获取用户人脸列表
	public static String getList(int userId) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/face/getlist";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("user_id", userId);
			map.put("group_id", "jcp");

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 获取指定组的用户列表
	public static String getUsers(String groupId) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getusers";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("group_id", groupId);

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 创建用户组
	public static String groupAdd(String groupId) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("group_id", groupId);

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 删除用户组
	public static String groupDelete(String groupId) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/delete";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("group_id", groupId);

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 组列表查询
	public static String GroupGetlist() {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist";
		try {
			Map<String, Object> map = new HashMap<>();
			map.put("start", 0);
			map.put("length", 100);

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 公安验证
	public static String personverify(String name, String imgAddress) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/person/verify";
		try {
			byte[] bytes = FileUtil.readFileByBytes(imgAddress);// 【本地文件地址】
			String img = Base64Util.encode(bytes);

			Map<String, Object> map = new HashMap<>();
			map.put("image", img);
			map.put("image_type", "BASE64");
			map.put("id_card_number", "1234");
			map.put("liveness_control", "HIGH");
			map.put("name", name);
			map.put("quality_control", "LOW");

			String param = GsonUtils.toJson(map);

			// 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
			String accessToken = "【调用鉴权接口获取的token】";

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 在线活体检测
	public static String faceVerify() {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceverify";
		try {
			Map<String, Object> map = new HashMap<>();
			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 人脸融合
	public static String facemerge(String imgAddress1, String imgAddress2) {
		// 请求url
		String url = "https://aip.baidubce.com/rest/2.0/face/v1/merge";
		try {
			byte[] bytes1 = FileUtil.readFileByBytes(imgAddress1);// 【本地文件地址】
			String img1 = Base64Util.encode(bytes1);
			byte[] bytes2 = FileUtil.readFileByBytes(imgAddress2);// 【本地文件地址】
			String img2 = Base64Util.encode(bytes2);

			Map<String, Object> map = new HashMap<>();

			Map<String, Object> image_templateMap = new HashMap<>();
			image_templateMap.put("image", img1);
			image_templateMap.put("image_type", "BASE64");
			image_templateMap.put("quality_control", "NONE");
			map.put("image_template", image_templateMap);

			Map<String, Object> image_targetMap = new HashMap<>();
			image_targetMap.put("image", img2);
			image_targetMap.put("image_type", "BASE64");
			image_targetMap.put("quality_control", "NONE");
			map.put("image_target", image_targetMap);

			String param = GsonUtils.toJson(map);

			String result = HttpUtil.post(url, accessToken, "application/json", param);
			System.out.println(result);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
